/**
 * All Rights Reserved , Copyright (C) 2022 , 青岛鼎信通讯股份有限公司
 * <p>
 * MpmProjectBidScoreService
 * 评标细则信息表
 * <p>
 * 修改纪录
 * 2022-04-24 版本：1.0 hudeyong 创建。
 *
 * @version 版本：1.0
 * @author 作者：hudeyong
 * 创建日期：2022-04-24
 */
package com.topscomm.mpm.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.sql.Clob;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.topscomm.basic.exception.BusinessException;
import com.topscomm.basic.exception.MessageException;
import com.topscomm.basic.util.SQLAdapter;
import com.topscomm.cbo.pojo.CboExcelImportConfigEntity;
import com.topscomm.cbo.pojo.CboUserEntity;
import com.topscomm.cbo.service.ICboMessageAppService;
import com.topscomm.cbo.service.ICboMessageSysService;
import com.topscomm.cbo.service.ICboUserService;
import com.topscomm.cbo.service.impl.CboExcelImportConfigService;
import com.topscomm.main.hessian.IBaseChangeLogService;
import com.topscomm.mpm.MpmSystemConst;
import com.topscomm.mpm.pojo.*;
import com.topscomm.mpm.service.IMpmProjectBidFullScoreService;
import com.topscomm.mpm.service.IMpmProjectReviewService;
import com.topscomm.mpm.utils.ConvertTimeUtil;
import com.topscomm.mpm.utils.MessageUtil;
import com.topscomm.pub.util.*;
import com.topscomm.pub.util.DateUtil;
import com.topscomm.tap.common.DatacodeCache;

import com.topscomm.tap.common.FlowDatacodeCache;
import com.topscomm.tap.common.TapSystemConst;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.topscomm.mpm.service.IMpmProjectBidScoreService;
import com.topscomm.mpm.service.impl.auto.MpmProjectBidScoreServiceAuto;
import com.topscomm.tap.TapEntity;
import com.topscomm.tap.common.SessionUserBean;
import com.topscomm.basic.BasicEntity;
import com.topscomm.basic.exception.ServiceException;
import com.topscomm.basic.util.PrimaryKeyUtil;
import com.topscomm.cbo.pojo.CboApprovalNodeEntity;
import com.topscomm.cbo.pojo.CboApprovalNodeInsEntity;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

@Service(value = "mpmProjectBidScoreService")
@Scope(value = "singleton")
public class MpmProjectBidScoreService extends MpmProjectBidScoreServiceAuto implements IMpmProjectBidScoreService {
    @Autowired
    private DatacodeCache datacodeCache;
    @Autowired
    private MpmProjectService mpmProjectService;
    @Autowired
    private ICboMessageAppService cboMessageAppService;
    @Autowired
    private ICboMessageSysService cboMessageSysService;
    @Autowired
    MpmProjectBidScoreHisService mpmProjectBidScoreHisService;
    @Autowired
    IBaseChangeLogService baseChangeLogService;
    @Autowired
    MpmProjectSaleService mpmProjectSaleService;
    @Autowired
    private MpmProjectVisitExpertService mpmProjectVisitExpertService;
    @Autowired
    private ICboUserService cboUserService;
    @Autowired
    private IMpmProjectBidFullScoreService mpmProjectBidFullScoreService;
    @Resource(name = "flowDatacodeCache")
    protected FlowDatacodeCache flowDatacodeCache;
    @Autowired
    public MpmProjectStakeholderService mpmProjectStakeholderService;
    @Autowired
    private MpmProjectMilepostService mpmProjectMilepostService;
    String tempTime = "2000/01/01 00:00:00";
    protected List<Map<String, Object>> flowidList = new ArrayList();

    /**
     * @author: hudeyong
     * @date: 2022-04-24
     * @param entity
     * @description:单号生成
     * @modify:
     */
    @Override
    protected void beforeInsert(BasicEntity entity) {
        super.beforeInsert(entity);
        if (entity.getId() <= 0) {// 赋值Id和单号
            long[] arrayId = PrimaryKeyUtil.GeneIDs(entity.getTableName(), 1);
            entity.setId(arrayId[0]);
            String docNo = String.valueOf(arrayId[0]);
            docNo = docNo.substring(0, 6) + docNo.substring(9);
            entity.setValue(MpmProjectBidScoreEntity.FieldDocno, docNo);
        }
    }

    /**
     * @Description: 转换出导出查询SQL语句
     * @Author: wuyuyang
     * @Return: java.lang.String
     * @exception:
     * @Date: 12/2/2023 下午8:47
     * @Version: 1.0
     **/
    public String spellListSql1(Map<String, Object> paraMap) {
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendSingle(" enabled=1 ");
        if (paraMap.containsKey("qry_state")) {
            String value = paraMap.get("qry_state").toString();
            if (!StringUtil.isEmpty(value))
                sql.appendSingle(" and state={0}", value);
        }
        if (paraMap.containsKey("qry_docno")) {
            String value = paraMap.get("qry_docno").toString();
            if (!StringUtil.isEmpty(value))
                sql.appendSingle(" and docno like '%{0}%'", value);
        }
        if (paraMap.containsKey("qry_begindocdate")) {
            String value = paraMap.get("qry_begindocdate").toString();
            if (!StringUtil.isEmpty(value))
                sql.appendSingle(" and docdate >= {0} ", SQLAdapter.toDateLong(value + " 00:00:00"));
        }
        if (paraMap.containsKey("qry_enddocdate")) {
            String value = paraMap.get("qry_enddocdate").toString();
            if (!StringUtil.isEmpty(value))
                sql.appendSingle(" and docdate <= {0}", SQLAdapter.toDateLong(value + " 23:59:59"));
        }
        if (paraMap.containsKey("qry_deptname")) {
            String value = paraMap.get("qry_deptname").toString();
            if (!StringUtil.isEmpty(value))
                sql.appendSingle(" and (deptid in ( SELECT id from CboDept where fullname like '%{0}%'))", value);
        }
        if (paraMap.containsKey("qry_username")) {
            String value = paraMap.get("qry_username").toString();
            if (!StringUtil.isEmpty(value))
                sql.appendSingle(" and (username like '%{0}%')", value);
        }
        if (paraMap.containsKey("qry_deptcode")) {
            String value = paraMap.get("qry_deptcode").toString();
            if (!StringUtil.isEmpty(value))
                sql.appendSingle(" and deptcode like '{0}%'", value);
        }
        if (paraMap.containsKey("qry_state")) {
            String value = paraMap.get("qry_state").toString();
            if (!StringUtil.isEmpty(value))
                sql.appendSingle(" and state={0}", value);
        }
        if (paraMap.containsKey("qry_where")) {
            String value = paraMap.get("qry_where").toString();
            if (!StringUtil.isEmpty(value))
                sql.appendSingle(" and {0}", value);
        }
        if (paraMap.containsKey("qry_projectcode")) {
            String value = paraMap.get("qry_projectcode").toString();
            if (!StringUtil.isEmpty(value))
                sql.appendSingle(" and projectcode='{0}'", value);
        }
        if (paraMap.containsKey("qry_type")) {
            String value = paraMap.get("qry_type").toString();
            if (!StringUtil.isEmpty(value))
                sql.appendSingle(" and type in ({0})", value);
        }
        if (paraMap.containsKey("qry_times")) {
            String value = paraMap.get("qry_times").toString();
            if (!StringUtil.isEmpty(value))
                sql.appendSingle(" and times in ({0})", value);
        }
        // 如果来自复盘页，则只看已发布的数据
        if (paraMap.containsKey("qry_fromreview")) {
            Boolean value = ConvertUtil.convertToBoolean(paraMap.get("qry_fromreview"));
            if (value) {
                sql.appendSingle(" and state = 9 ");
            }
        }
        if (this.getSessionUserBean().getUser().getAdminlevel() < 1)// 管理员、超级管理员，不控制权限
        {
            String dataPession = this.getDataPermission(TapSystemConst.TapOperationTypeEnum.Select, "", this.getSessionUserBean());
            if (StringUtil.isEmpty(dataPession))// 默认权限只能看本人，部门负责人为自己的部门和下级部门的数据
            {
            } else// 使用数据权限
            {
                sql.appendSingle(" and {0} ", dataPession);
            }
        }
        // 审批时可以看所有，其余只能看已发布
        if (paraMap.containsKey("isapproval")) {
            boolean value = ConvertUtil.convertToBoolean(paraMap.get("isapproval"));
            if (!value) {
                sql.appendSingle(" and (state = '9' or usercode = '{0}')", this.getSessionUserBean().getUser().getCode());
            } else {
                sql.appendSingle(" and state = '1'");
            }
        }
        return sql.toString();
    }

    @Override
    public void setDispFields(Map<String, Object> mapRow, DatacodeCache datacodeCache) {
        String temp;
        if (mapRow.get("projectmanagercode") != null) {
            temp = mapRow.get("projectmanagercode").toString();
            mapRow.put("dispprojectmanagercode", datacodeCache.getValueDynamic("CboUser", temp, "code", "name"));
        }
        if (mapRow.get("deptcommoncode") != null) {
            temp = mapRow.get("deptcommoncode").toString();
            mapRow.put("dispdeptcommoncode", datacodeCache.getValueDynamic("DeptCommonCodeTrack", temp, "code", "name"));
        }
        super.setDispFields(mapRow, datacodeCache);
    }

    /**
     * @author: hdy
     * @date: 2022-04-27
     * @param map
     * @return_type: void
     * @description:更新后处理
     * @modify:
     */
    @Override
    protected void updateAfter(Map<String, Object> map) throws ServiceException {
        super.updateAfter(map);
        String state = ConvertUtil.convertToString(map.get("state"));
        //  已发布、变更的才记录历史
        if ("9".equals(state) && map.containsKey("isChange") && true == ConvertUtil.convertToBoolean(map.containsKey("isChange"))) {
            // 变更后向投标部人员发送消息
            this.sendMessageToBid(ConvertUtil.convertToString(map.get("projectcode")), ConvertUtil.convertToString(map.get("times")), "change");
            // 记录历史
            MpmProjectBidScoreEntity scoreEntity = new MpmProjectBidScoreEntity();
            scoreEntity.convertFromMap(map);
            StringBufferProxy sql = new StringBufferProxy();
            sql.appendSingle("SOURCEID = '{0}' ORDER BY TO_NUMBER(VERSION) DESC ", scoreEntity.getId());
            List<MpmProjectBidScoreHisEntity> mpmProjectBidScoreHisEntities = mpmProjectBidScoreHisService.queryByWhere(sql.toString());
            int version = 1;
            if (mpmProjectBidScoreHisEntities.size() > 0) {
                version = ConvertUtil.convertToInt(mpmProjectBidScoreHisEntities.get(0).getVersion()) + 1;
            }
            // 是否需要插入记录
            boolean key = baseChangeLogService.isSaveChangeLog(map, scoreEntity.getTableName(), version + "");
            if (!key) {
                return;
            }
            MpmProjectBidScoreHisEntity mpmProjectBidScoreHisEntity = new MpmProjectBidScoreHisEntity();
            long[] arrayId = PrimaryKeyUtil.GeneIDs(mpmProjectBidScoreHisEntity.getTableName(), 1);
            BeanUtils.copyProperties(scoreEntity, mpmProjectBidScoreHisEntity);
            mpmProjectBidScoreHisEntity.setId(arrayId[0]);
            mpmProjectBidScoreHisEntity.setVersion(version + "");
            mpmProjectBidScoreHisEntity.setSourceid(ConvertUtil.convertToLong(map.get("id")));
            mpmProjectBidScoreHisService.insert(mpmProjectBidScoreHisEntity);
            //没打标的
            if (map.containsKey("bidscoreflag") && "0".equals(ConvertUtil.convertToString(map.get("bidscoreflag")))) {
                String ordercode = ConvertUtil.convertToString(scoreEntity.getId());
                sql.clear();
                sql.appendSingle("ordercode = '{0}'", ordercode);
                List<MpmProjectBidScoreEntity> mpmProjectBidScoreEntities = this.queryByWhere(sql.toString());
                if (mpmProjectBidScoreEntities.size() > 0 && this.judgeIdSecond(mpmProjectBidScoreEntities.get(0).getProjectcode())) {
                    String secondid = ConvertUtil.convertToString(mpmProjectBidScoreEntities.get(0).getId());
                    this.deleteById(secondid);
                    MpmProjectBidScoreEntity newScoreEntity = new MpmProjectBidScoreEntity();
                    newScoreEntity.setType(scoreEntity.getType());
                    newScoreEntity.setTimes("2");
                    newScoreEntity.setProjectcode(scoreEntity.getProjectcode());
                    newScoreEntity.setScoringitem_big_catergory(scoreEntity.getScoringitem_big_catergory());
                    newScoreEntity.setScoringitem_small_catergory(scoreEntity.getScoringitem_small_catergory());
                    newScoreEntity.setScoringrubric(scoreEntity.getScoringrubric());
                    newScoreEntity.setScoredescription(scoreEntity.getScoredescription());
                    newScoreEntity.setFullscore(scoreEntity.getFullscore());
                    newScoreEntity.setSelfscore(scoreEntity.getSelfscore());
                    newScoreEntity.setTargetscore(scoreEntity.getTargetscore());
                    newScoreEntity.setScoregap(scoreEntity.getScoregap());
                    newScoreEntity.setGapanalysis(scoreEntity.getGapanalysis());
                    newScoreEntity.setScoringplan(scoreEntity.getScoringplan());
                    newScoreEntity.setResponsiblecode(scoreEntity.getResponsiblecode());
                    newScoreEntity.setResponsible(scoreEntity.getResponsible());
                    newScoreEntity.setDeptcode(scoreEntity.getDeptcode());
                    newScoreEntity.setDeptname(scoreEntity.getDeptname());
                    newScoreEntity.setOrdercode(ConvertUtil.convertToString(scoreEntity.getId()));
                    newScoreEntity.setUsercode(scoreEntity.getUsercode());
                    newScoreEntity.setUsername(scoreEntity.getUsername());
                    newScoreEntity.setFlowid(scoreEntity.getFlowid());
                    newScoreEntity.setImprovescore("0");
                    arrayId = PrimaryKeyUtil.GeneIDs(newScoreEntity.getTableName(), 1);
                    newScoreEntity.setId(ConvertUtil.convertToLong(secondid));
                    this.insert(newScoreEntity);
                }
            }
        }
    }

    /**
     *
     * @description: 判断是否已经到达第二次自评
     * @author: hdy
     * @date: 2022年5月16日
     * @modify:
     */
    private boolean judgeIdSecond(String projectcode) {
        boolean key = false;
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendSingle("id = (select id from mpmproject where  projectcode = '{0}')", projectcode);
        List<MpmProjectSaleEntity> mpmProjectSaleEntities = mpmProjectSaleService.queryByWhere(sql.toString());
        if (mpmProjectSaleEntities.size() > 0) {
            Date bidenddate = mpmProjectSaleEntities.get(0).getBidbegindate();
            if (bidenddate != null && bidenddate.after(new Date())) {
                // 挂网大于当前
                key = true;
            } else if (bidenddate != null && bidenddate.before(new Date())) {
                // 挂网小于当前
                key = false;
            }
        }
        return key;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertThirdTimeScoreInfo(String projectCode) {
        // 删除第三次的
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendSingle(" {0} = '{1}' ", MpmProjectBidScoreEntity.FieldProjectcode, projectCode);
        sql.appendSingle(" and {0} = '{1}' ", MpmProjectBidScoreEntity.FieldTimes, "3");
        deleteByWhere(sql.toString());
        sql.clear();
        sql.appendSingle(" {0} = '{1}' ", MpmProjectBidScoreEntity.FieldProjectcode, projectCode);
        sql.appendSingle(" and {0} = {1} ", MpmProjectBidScoreEntity.FieldState, TapSystemConst.TapApprovalFlowStateEnum.Approved);
        List<MpmProjectBidScoreEntity> list = this.queryByWhere(sql.toString());
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        // 按照次数分组
        Map<String, List<MpmProjectBidScoreEntity>> timeMap = list.stream().collect(Collectors.groupingBy(MpmProjectBidScoreEntity::getTimes));
        List<MpmProjectBidScoreEntity> mpmProjectBidScoreEntities = Optional.ofNullable(timeMap.get("2")).orElse(timeMap.get("1"));
        if (CollectionUtils.isEmpty(mpmProjectBidScoreEntities)) {
            return;
        }
        List<BasicEntity> insertScoreEntityList = new ArrayList<>();
        MpmProjectBidScoreEntity temp;
        for (MpmProjectBidScoreEntity entity : mpmProjectBidScoreEntities) {
            temp = new MpmProjectBidScoreEntity();
            BeanUtils.copyProperties(entity, temp);
            temp.setId(0L);
            temp.setState(TapSystemConst.TapApprovalFlowStateEnum.Open);
            temp.setTimes("3");
            insertScoreEntityList.add(temp);
        }
        insertBatch(insertScoreEntityList);

        // 复制第二次要求高于分数
        sql.clear();
        sql.appendSingle(" {0} = '{1}' ", MpmProjectBidFullScoreEntity.FieldProjectcode, projectCode);
        sql.appendSingle(" and {0} = '{1}' ", MpmProjectBidFullScoreEntity.FieldTimes, "3");
        mpmProjectBidFullScoreService.deleteByWhere(sql.toString());
        List<MpmProjectBidFullScoreEntity> secondTimeList = mpmProjectBidFullScoreService.queryByTime(projectCode, "2");
        if (CollectionUtils.isEmpty(secondTimeList)) {
            return;
        }
        List<BasicEntity> thirdTimeList = new ArrayList<>();
        MpmProjectBidFullScoreEntity third;
        for (MpmProjectBidFullScoreEntity second : secondTimeList) {
            third = new MpmProjectBidFullScoreEntity();
            BeanUtils.copyProperties(second, third);
            third.setId(0L);
            third.setTimes("3");
            thirdTimeList.add(third);
        }
        mpmProjectBidFullScoreService.insertBatch(thirdTimeList);
    }

    @Autowired
    private IMpmProjectReviewService mpmProjectReviewService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String initHistoryThirdScore() {
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendSingle(" {0} = '{1}' ", MpmProjectBidScoreEntity.FieldTimes, "3");
        List<MpmProjectBidScoreEntity> thirdList = queryByWhere(sql.toString());

        sql.clear();
        sql.appendSingle(" {0} = {1} ", MpmProjectBidScoreEntity.FieldState, TapSystemConst.TapApprovalFlowStateEnum.Approved);
        sql.appendSingle(" and {0} != '{1}' ", MpmProjectBidScoreEntity.FieldTimes, "3");
        List<MpmProjectBidScoreEntity> secondAndFirstList = queryByWhere(sql.toString());
        if (CollectionUtils.isEmpty(secondAndFirstList)) {
            return "未查询到前两次评分数据";
        }
        List<BasicEntity> thirdTimeList = new ArrayList<>();
        Set<String> existsThirdProjectCodeSet = null;
        if (CollectionUtils.isEmpty(thirdList)) {
            existsThirdProjectCodeSet = thirdList.stream().map(MpmProjectBidScoreEntity::getProjectcode).collect(Collectors.toSet());
        }
        // 查询复盘
        List<MpmProjectReviewEntity> mpmProjectReviewEntities = mpmProjectReviewService.queryByWhere("1 = 1");
        Map<String, Integer> reviewState = null;
        if (!CollectionUtils.isEmpty(mpmProjectReviewEntities)) {
            reviewState = mpmProjectReviewEntities.stream().collect(Collectors.toMap(MpmProjectReviewEntity::getProjectcode, MpmProjectReviewEntity::getState, (v1, v2) -> v1));
        } else {
            reviewState = new HashMap<>();
        }

        // 先根据项目编码分组
        Map<String, List<MpmProjectBidScoreEntity>> groupByProjectCodeMap = secondAndFirstList.stream().collect(Collectors.groupingBy(MpmProjectBidScoreEntity::getProjectcode));
        for (Map.Entry<String, List<MpmProjectBidScoreEntity>> entry : groupByProjectCodeMap.entrySet()) {
            if (CollectionUtils.isEmpty(entry.getValue())) {
                // 没有数据则跳过
                continue;
            }
            String projectCode = entry.getKey();
            if (existsThirdProjectCodeSet != null && existsThirdProjectCodeSet.contains(projectCode)) {
                // 已经存在该项目的第三次自评，则不需要增加第三次自评
                continue;
            }
            // 再根据评分次数分组
            Map<String, List<MpmProjectBidScoreEntity>> groupByTimeMap = entry.getValue().stream().collect(Collectors.groupingBy(MpmProjectBidScoreEntity::getTimes));
            List<MpmProjectBidScoreEntity> mpmProjectBidScoreEntities = Optional.ofNullable(groupByTimeMap.get("2")).orElse(groupByTimeMap.get("1"));
            if (CollectionUtils.isEmpty(mpmProjectBidScoreEntities)) {
                // 没有第一次和第二次则跳过
                continue;
            }
            MpmProjectBidScoreEntity third;
            for (MpmProjectBidScoreEntity entity : mpmProjectBidScoreEntities) {
                third = new MpmProjectBidScoreEntity();
                BeanUtils.copyProperties(entity, third);
                third.setId(0L);
                third.setState(Optional.ofNullable(reviewState.get(projectCode)).orElse(TapSystemConst.TapApprovalFlowStateEnum.Open));
                third.setTimes("3");
                thirdTimeList.add(third);
            }
        }
        insertBatch(thirdTimeList);
        return "查询到已有第三次自评的条数为" + thirdList.size() + "查询的第二次或者第一次的条数为" + secondAndFirstList.size() + "插入条数" + thirdTimeList.size();
    }

    @Override
    public int queryScoreTimes(String projectCode) {
        if (StringUtil.isEmpty(projectCode)) {
            throw new SecurityException("项目编码不能为空");
        }

        StringBufferProxy sql = new StringBufferProxy();
        sql.appendSingle(" {0} = {1} and times in ({2}) and type in ({3}) ", MpmProjectBidScoreEntity.FieldState, TapSystemConst.TapApprovalFlowStateEnum.Approved,
                MpmSystemConst.BidScoreTimes.firstTime + "," + MpmSystemConst.BidScoreTimes.secondTime, MpmSystemConst.BidScoreType.firstType + "," + MpmSystemConst.BidScoreType.secondType);
        sql.appendSingle(" and {0} = '{1}' ", MpmProjectBidScoreEntity.FieldProjectcode, projectCode);
        List<MpmProjectBidScoreEntity> list = queryByWhere(sql.toString());
        if (CollectionUtils.isEmpty(list)) {
            return 4; //未自评
        }
        Set<String> timeSet = list.stream().map(MpmProjectBidScoreEntity::getTimes).distinct().collect(Collectors.toSet());
        boolean haveFirst = timeSet.contains("1");
        boolean haveSecond = timeSet.contains("2");
        if (haveFirst && haveSecond) {
            return 1; // 两次均已完成
        }
        if (haveFirst) {
            return 2; // 只完成第一次
        }
        return 3; // 只完成第二次
    }

    /**
     *
     * @description: 审批通过后的处理
     * @param billEntity
     * @param nodeIns
     * @param node
     * @param sessionUserBean
     * @author: hdy
     * @date: 2022年4月26日
     * @modify:
     */
    @Override
    protected void afterApprove(TapEntity billEntity, CboApprovalNodeInsEntity nodeIns, CboApprovalNodeEntity node,
                                SessionUserBean sessionUserBean) {
        String soucreid = ConvertUtil.convertToString(nodeIns.getSourceid());
        MpmProjectBidScoreEntity mpmProjectBidScoreEntity = this.queryById(soucreid);
        if (mpmProjectBidScoreEntity == null) {
            return;
        }
        String projectcode = mpmProjectBidScoreEntity.getProjectcode();
        String times = mpmProjectBidScoreEntity.getTimes();
        String state = ConvertUtil.convertToString(mpmProjectBidScoreEntity.getState());
        StringBufferProxy sql = new StringBufferProxy();
        // 添加审批轮次
        if ("9".equals(state)) {
            sql.clear();
            sql.appendSingle("projectcode = '{0}' and approvaltimes is not null order by approvaltimes desc", projectcode);
            List<MpmProjectBidScoreEntity> approvalBidScoreEntities = this.queryByWhere(sql.toString());
            int index = 1;
            if (approvalBidScoreEntities.size() != 0) {
                index = ConvertUtil.convertToInt(approvalBidScoreEntities.get(0).getApprovaltimes()) + 1;
            }
            sql.clear();
            sql.appendSingle("UPDATE MPMPROJECTBIDSCORE SET approvaltimes = '{0}' WHERE projectcode = '{1}' and (state = 1 or id = {2})",
                    index, projectcode, soucreid);
            this.updateExecute(sql.toString());
        }
        // 如果是第一次且审批通过，自动生成第二次
        if ("1".equals(times) && "9".equals(state)) {
            sql.clear();
            sql.appendSingle("projectcode = '{0}' and (state = 1 or id = {1}) order by id", projectcode, soucreid);
            List<MpmProjectBidScoreEntity> mpmProjectBidScoreEntities = this.queryByWhere(sql.toString());
            for (MpmProjectBidScoreEntity scoreEntity : mpmProjectBidScoreEntities) {
                MpmProjectBidScoreEntity newScoreEntity = new MpmProjectBidScoreEntity();
                newScoreEntity.setType(scoreEntity.getType());
                newScoreEntity.setTimes("2");
                newScoreEntity.setProjectcode(scoreEntity.getProjectcode());
                newScoreEntity.setScoringitem_big_catergory(scoreEntity.getScoringitem_big_catergory());
                newScoreEntity.setScoringitem_small_catergory(scoreEntity.getScoringitem_small_catergory());
                newScoreEntity.setScoringrubric(scoreEntity.getScoringrubric());
                newScoreEntity.setScoredescription(scoreEntity.getScoredescription());
                newScoreEntity.setFullscore(scoreEntity.getFullscore());
                newScoreEntity.setSelfscore(scoreEntity.getSelfscore());
                newScoreEntity.setTargetscore(scoreEntity.getTargetscore());
                newScoreEntity.setScoregap(scoreEntity.getScoregap());
                newScoreEntity.setIsexpertguide(scoreEntity.getIsexpertguide());
                newScoreEntity.setGapanalysis(scoreEntity.getGapanalysis());
                newScoreEntity.setScoringplan(scoreEntity.getScoringplan());
                newScoreEntity.setResponsiblecode(scoreEntity.getResponsiblecode());
                newScoreEntity.setResponsible(scoreEntity.getResponsible());
                newScoreEntity.setDeptcode(scoreEntity.getDeptcode());
                newScoreEntity.setDeptname(scoreEntity.getDeptname());
                newScoreEntity.setUsercode(scoreEntity.getUsercode());
                newScoreEntity.setUsername(scoreEntity.getUsername());
                newScoreEntity.setFlowid(scoreEntity.getFlowid());
                newScoreEntity.setImprovescore("0");
                newScoreEntity.setOrdercode(ConvertUtil.convertToString(scoreEntity.getId()));
                long[] arrayId = PrimaryKeyUtil.GeneIDs(newScoreEntity.getTableName(), 1);
                newScoreEntity.setId(arrayId[0]);
                this.insert(newScoreEntity);
            }
        }
        // 评标细则审批通过后，给责任人、投标部人员发送APP消息提醒,赋值主表自评信息
        if ("9".equals(state)) {
            this.sendMessageToResponsible(projectcode, times, soucreid);
            this.sendMessageToBid(projectcode, times, "approval");
        }
        sql.clear();
        sql.appendSingle("update MPMPROJECTBIDSCORE set state = '{0}' where projectcode = '{1}' and times = '{2}' and state = 1", state, projectcode, times);
        this.updateExecute(sql.toString());
        if ("9".equals(state)) {
            // 审批通过后,将商务、技术、报价总分写入主表
            this.updateProjectBidScore(projectcode, times, "", "");
            // 审批通过后，生成历史记录
            sql.clear();
            sql.appendSingle("projectcode = '{0}' and times = '{1}' and type in (1,2) ", projectcode, times);
            List<MpmProjectBidScoreEntity> mpmProjectBidScoreEntities = this.queryByWhere(sql.toString());
            for (MpmProjectBidScoreEntity scoreEntity : mpmProjectBidScoreEntities) {
                MpmProjectBidScoreHisEntity mpmProjectBidScoreHisEntity = new MpmProjectBidScoreHisEntity();
                long[] arrayId = PrimaryKeyUtil.GeneIDs(mpmProjectBidScoreHisEntity.getTableName(), 1);
                BeanUtils.copyProperties(scoreEntity, mpmProjectBidScoreHisEntity);
                mpmProjectBidScoreHisEntity.setId(arrayId[0]);
                mpmProjectBidScoreHisEntity.setVersion("0");
                mpmProjectBidScoreHisEntity.setSourceid(scoreEntity.getId());
                mpmProjectBidScoreHisService.insert(mpmProjectBidScoreHisEntity);
            }
        }
        super.afterApprove(billEntity, nodeIns, node, sessionUserBean);
    }

    /**
     *
     * @description: 评标细则审批通过后，给责任人发送APP消息提醒
     * @author: houyuhang
     * @date: 2022年4月27日
     * @modify:
     */
    public void sendMessageToResponsible(String projectcode, String times, String soucreid) {
        StringBufferProxy sql = new StringBufferProxy();
        // 获取该项目本次自评的记录
        sql.appendSingle(" {0}.{1} = '{2}' and {3} = '{4}' and ({0}.state = 1 or {0}.id = {5}) and {0}.type in (1,2) ", MpmProjectBidScoreEntity.tableName, MpmProjectBidScoreEntity.FieldProjectcode, projectcode,
                MpmProjectBidScoreEntity.FieldTimes, times, soucreid);
        List<Map<String, Object>> mpmProjectBidScoreEntities = mpmProjectService.queryMapByWhere(sql.toString(), "bidScoreSoonOverdue");
        // 同一个人的自评记录只发一条消息,此时评分细则和细则描述为clob值，不能直接使用，如需使用需要转成string
        List<Map<String, Object>> mpmProjectBidScoreEntitiesFilter = mpmProjectBidScoreEntities.stream().filter(distinctByKey(item -> item.get("responsiblecode"))).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(mpmProjectBidScoreEntitiesFilter)) {
            return;
        }
        List<Map<String, Object>> appList = new ArrayList<>();
        List<Map<String, Object>> sysList = new ArrayList<>();
        sql.clear();
        sql.appendSingle("projectcode = '{0}'", projectcode);
        List<MpmProjectEntity> mpmProjectEntities = mpmProjectService.queryByWhere(sql.toString());
        if (mpmProjectEntities.size() == 0) {
            return;
        }
        long mpmId = mpmProjectEntities.get(0).getId();
        for (Map<String, Object> mpmProjectBidScoreEntity : mpmProjectBidScoreEntitiesFilter) {
            StringBufferProxy content = new StringBufferProxy();
            String projectLevel = datacodeCache.getValueDynamic("MpmProjectLevel", ConvertUtil.convertToString(mpmProjectBidScoreEntity.get("projectlevel")), "code", "name");
            String projectName = ConvertUtil.convertToString(mpmProjectBidScoreEntity.get("projectname"));
            String responsibleCode = ConvertUtil.convertToString(mpmProjectBidScoreEntity.get("responsiblecode"));
            String responsible = ConvertUtil.convertToString(mpmProjectBidScoreEntity.get("responsible"));
//			long mpmId = ConvertUtil.convertToLong(mpmProjectBidScoreEntity.get("mpmid"));
            content.appendSingle("您有来自【{0}级项目：{1}】的评分细则任务需要完成，请及时前往对应项目的评分细则模块查阅", projectLevel, projectName);
            String sourcetype = MpmSystemConst.ProjectScoreCode.first;
            if (times.equals(MpmSystemConst.BidScoreType.secondType)) {
                sourcetype = MpmSystemConst.ProjectScoreCode.second;
            }
            // 插入App消息
            Map<String, Object> taskappmap = mpmProjectService.insertMessageApp(responsibleCode, "销售项目评分细则任务提醒", content.toString(),
                    mpmId, sourcetype, 0);
            appList.add(taskappmap);
            // 插入系统消息
            Map<String, Object> tasksysmap = mpmProjectService.insertMessageSys(responsibleCode, responsible, "销售项目评分细则任务提醒", content.toString(),
                    mpmId, sourcetype);
            sysList.add(tasksysmap);
        }
        cboMessageAppService.insertList(appList);
        cboMessageSysService.insertList(sysList);
    }

    //过滤重复数据
    private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object, Boolean> map = new ConcurrentHashMap<>();
        return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

    /**
     *
     * @description: 将clob类型数据转换为string类型（querymap时需要使用此方法）
     * @author: houyuhang
     * @date: 2022年6月20日
     * @modify:
     */
    @Override
    public void convertClobToStringBidScore(List<Map<String, Object>> list) throws Exception {
        for (Map<String, Object> map : list) {
            String scoringrubricStr = ConvertUtil.clobToString((Clob) map.get("scoringrubric"));
            map.put("scoringrubric", scoringrubricStr);
            String scoredescriptionStr = ConvertUtil.clobToString((Clob) map.get("scoredescription"));
            map.put("scoredescription", scoredescriptionStr);
        }
    }

    /**
     *
     * @description: 省招A级项目，任命审批通过后对项目经理发送第一次自评提醒
     * @author: houyuhang
     * @date: 2022年7月22日
     * @modify:
     */
    public void sendBidScoreMessageAfterAppointment(MpmProjectEntity mpmProjectEntity) {
        if (!judgeProvinceBidALevel(mpmProjectEntity.getProjectcode())) {
            return;
        }
        List<Map<String, Object>> appList = new ArrayList<>();
        List<Map<String, Object>> sysList = new ArrayList<>();
        StringBufferProxy content = new StringBufferProxy();
        long mpmId = mpmProjectEntity.getId();
        String responsibleCode = mpmProjectEntity.getProjectmanagercode();
        String responsible = mpmProjectEntity.getProjectmanager();
        String projectlevel = datacodeCache.getValueDynamic("MpmProjectLevel", mpmProjectEntity.getProjectlevel(), "code", "name");
        String projectname = mpmProjectEntity.getProjectname();
        content.appendSingle("【{0}级项目：{1}】项目任命已发布，请尽快组织完成评分细则第一次自评。", projectlevel, projectname);
        // 插入App消息
        Map<String, Object> taskappmap = mpmProjectService.insertMessageApp(responsibleCode, "第一次自评提醒", content.toString(),
                mpmId, MpmProjectAppointmentEntity.tableName, 0);
        appList.add(taskappmap);
        // 插入系统消息
        Map<String, Object> tasksysmap = mpmProjectService.insertMessageSys(responsibleCode, responsible, "第一次自评提醒", content.toString(),
                mpmId, MpmProjectAppointmentEntity.tableName);
        sysList.add(tasksysmap);
        cboMessageAppService.insertList(appList);
        cboMessageSysService.insertList(sysList);
    }

    /**
     * @description: 判断是否为省招A级项目
     * @author: houyuhang
     * @date: 2022年7月25日
     * @modify:
     */
    public boolean judgeProvinceBidALevel(String projectcode) {
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendSingle(" projectcode = '{0}' and projectlevel = '{1}' and {2} in ('{3}','{5}') and clientlevel like '%{4}%' ",
                projectcode, MpmSystemConst.ProjectLevel.A, MpmProjectSaleEntity.FieldPurchasepattern, MpmSystemConst.PurchasePattern.chanpinBid, MpmSystemConst.ClientLevel.Province, MpmSystemConst.PurchasePattern.dianshang);
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("whereSql", sql.toString());
        int count = mpmProjectService.getCount(dataMap, "projectALevel");
        return count > 0;
    }

    /**
     * @description: 审批结束后向投标部人员发送消息提醒
     * @author: houyuhang
     * @date: 2022年11月25日
     * @modify:
     */
    public void sendMessageToBid(String projectcode, String times, String messagetype) {
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendSingle(" enabled = 1 and projectcode = '{0}' ", projectcode);
        MpmProjectEntity mpmProjectEntity = mpmProjectService.queryObjectByWhere(sql.toString());
        if (ObjectUtil.isEmpty(mpmProjectEntity)) {
            return;
        }
        // 封装消息内容
        String projectLevel = datacodeCache.getValueDynamic("MpmProjectLevel", mpmProjectEntity.getProjectlevel(), "code", "name");
        List<Map<String, Object>> appList = new ArrayList<>(), sysList = new ArrayList<>();
        Map<String, Object> appMap = new HashMap<>(), sysMap = new HashMap<>();
        String title = "销售项目评分细则提醒";
        StringBufferProxy content = new StringBufferProxy();
        String timeStr = "1".equals(times) ? "一" : "二";
        content.appendSingle("【{0}级项目：{1}】评分细则第{2}次自评{3}，请登录销售项目管理系统查看。", projectLevel, mpmProjectEntity.getProjectname(), timeStr, "approval".equals(messagetype) ? "发布审批通过" : "已变更");
        // 获取发送人员
        List<String> sendUser = mpmProjectVisitExpertService.queryBidUser(mpmProjectEntity);
        if (CollectionUtil.isEmpty(sendUser)) {
            return;
        }
        String sendUserStr = sendUser.stream().collect(Collectors.joining("','", "'", "'"));
        sql.clear();
        sql.appendSingle(" enabled = 1 and code in ({0}) ", sendUserStr);
        List<CboUserEntity> cboUserEntities = cboUserService.queryByWhere(sql.toString());
        Map<String, List<CboUserEntity>> cboUserMap = cboUserEntities.stream().collect(Collectors.groupingBy(CboUserEntity::getCode));
        String sourcetype = MpmSystemConst.ProjectScoreCode.first;
        if (times.equals(MpmSystemConst.BidScoreType.secondType)) {
            sourcetype = MpmSystemConst.ProjectScoreCode.second;
        }
        for (String user : sendUser) {
            // app推送
            appMap = MessageUtil.createMessageAppMap(user, title, content.toString(), mpmProjectEntity.getId(),
                    sourcetype, 0);
            // 系统消息
            sysMap = MessageUtil.createMessageSysMap(user, CollectionUtil.isEmpty(cboUserMap.get(user)) ? "" : cboUserMap.get(user).get(0).getName(), title, content.toString(),
                    mpmProjectEntity.getId(), sourcetype);
            // 封装
            appList.add(appMap);
            sysList.add(sysMap);
        }
        // 消息批量插入
        cboMessageAppService.insertList(appList);
        cboMessageSysService.insertList(sysList);
    }

    /**
     * @description: 更新主表评分细则信息
     * @author: houyuhang
     * @date: 2022年12月13日
     * @modify:
     */
    @Transactional
    public void updateProjectBidScore(String projectcode, String times, String quality, String ability) {
        // 获取本次自评信息
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendSingle(" projectcode = '{0}' and times = '{1}' and state = 9 ", projectcode, times);
        List<MpmProjectBidScoreEntity> mpmProjectBidScoreEntities = this.queryByWhere(sql.toString());
        double scoretype1 = mpmProjectBidScoreEntities.stream().filter(item -> MpmSystemConst.BidScoreType.firstType.equals(item.getType())).mapToDouble(item -> ConvertUtil.convertToDouble(item.getSelfscore())).sum();
        double scoretype2 = mpmProjectBidScoreEntities.stream().filter(item -> MpmSystemConst.BidScoreType.secondType.equals(item.getType())).mapToDouble(item -> ConvertUtil.convertToDouble(item.getSelfscore())).sum();
        double scoretype3 = 0.0d;
        if (MpmSystemConst.BidScoreTimes.secondTime.equals(times)) {
            scoretype3 = mpmProjectBidScoreEntities.stream().filter(item -> MpmSystemConst.BidScoreType.thirdType.equals(item.getType())).mapToDouble(item -> ConvertUtil.convertToDouble(item.getTargetscore())).sum();
        } else if (MpmSystemConst.BidScoreTimes.thirdTime.equals(times)) {
            scoretype3 = mpmProjectBidScoreEntities.stream().filter(item -> MpmSystemConst.BidScoreType.thirdType.equals(item.getType())).mapToDouble(item -> ConvertUtil.convertToDouble(item.getCompletionscore())).sum();
        }
        StringBuffer stringBuffer = new StringBuffer();
        DecimalFormat df = new DecimalFormat("#.0");
        if (scoretype1 > 1e-15) {
            stringBuffer.append("商务" + df.format(scoretype1).replace(".0", "") + "、");
        }
        if (scoretype2 > 1e-15) {
            stringBuffer.append("技术" + df.format(scoretype2).replace(".0", "") + "、");
        }
        if (scoretype3 > 1e-15) {
            stringBuffer.append("报价" + df.format(scoretype3).replace(".0", "") + "、");
        }
        if (!StringUtil.isEmpty(quality)) {
            stringBuffer.append("运行质量" + quality + "、");
        }
        if (!StringUtil.isEmpty(ability)) {
            stringBuffer.append("资质能力" + ability + "、");
        }
        String bidscore = stringBuffer.toString().substring(0, stringBuffer.length() > 0 ? stringBuffer.length() - 1 : 0);
        sql.clear();
        sql.appendSingle(" enabled = 1 and projectcode = '{0}' ", projectcode);
        MpmProjectEntity mpmProjectEntity = mpmProjectService.queryObjectByWhere(sql.toString());
        if (MpmSystemConst.BidScoreTimes.firstTime.equals(times)) {
            mpmProjectEntity.setFirstbidscore(bidscore);
        } else if (MpmSystemConst.BidScoreTimes.secondTime.equals(times)) {
            mpmProjectEntity.setSecondbidscore(bidscore);
        } else if (MpmSystemConst.BidScoreTimes.thirdTime.equals(times)) {
            mpmProjectEntity.setThirdbidscore(bidscore);
        }
        mpmProjectService.updateEntity(mpmProjectEntity);
    }

    /**
     * @Description: 初始化历史数据-主表一二三次自评数据
     * @Author: houyuhang
     * @Date: 2022/12/14
     **/
    public void initHistoryBidScoreInfo() {
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendSingle(" enabled = 1 and state = 9 and exists (select 1 from mpmprojectbidscore WHERE mpmprojectbidscore.projectcode = mpmproject.projectcode AND state = 9) ");
        List<MpmProjectEntity> mpmProjectEntities = mpmProjectService.queryByWhere(sql.toString());
        for (MpmProjectEntity mpmProjectEntity : mpmProjectEntities) {
            String quality = "";
            String ability = "";
            String projectcode = mpmProjectEntity.getProjectcode();
            sql.clear();
            sql.appendSingle(" enabled = 1 and state = 9 and projectcode = '{0}' ", projectcode);
            List<MpmProjectReviewEntity> mpmProjectReviewEntities = mpmProjectReviewService.queryByWhere(sql.toString());
            if (!CollectionUtil.isEmpty(mpmProjectReviewEntities)) {
                quality = mpmProjectReviewEntities.get(0).getQualityscore();
                ability = mpmProjectReviewEntities.get(0).getAbilityscore();
            }
            this.updateProjectBidScore(projectcode, "1", "", "");
            this.updateProjectBidScore(projectcode, "2", "", "");
            this.updateProjectBidScore(projectcode, "3", quality, ability);
        }
    }

    /**
     * @Description: 处理导入数据
     * @Author: wuyuyang
     * @Return: int
     * @exception:
     * @Date: 11/2/2023 下午3:01
     * @Version: 1.0
     **/
    @Transactional
    public int dealImportData(Map<String, Object> paraMap, File file) {
        // 导入数据
        return this.executeImportExcel(paraMap, file);
    }

    /**
     * @Description: 导入数据插入前处理
     * @Author: wuyuyang
     * @Return: int
     * @exception:
     * @Date: 11/2/2023 下午3:10
     * @Version: 1.0
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int executeImportExcel(Map<String, Object> paraMap, File attachFile) {
        // 获取表名、次数、项目编号
        String tableName = ConvertUtil.convertToString(paraMap.get("tableName"));
        String times = ConvertUtil.convertToString(paraMap.get("times"));
        String projectinfocode = ConvertUtil.convertToString(paraMap.get("projectinfocode"));
        // 获取满分合计分数
        String businessFullScore = ConvertUtil.convertToString(paraMap.get("businessFullScore"));
        String technologyFullScore = ConvertUtil.convertToString(paraMap.get("technologyFullScore"));

        if (tableName.length() == 0) {
            throw new ServiceException("请联系管理员配置数据库表");
        }
        CboExcelImportConfigService configService = (CboExcelImportConfigService) SpringUtil
                .getBean("cboExcelImportConfigService");
        List<CboExcelImportConfigEntity> listConfig = configService.queryByWhere("tablename='" + tableName + "'");
        if (listConfig == null || listConfig.size() < 1)
            throw new ServiceException("没有维护excel导入配置，表名为：" + tableName);
        // excel有效起始行
        int importStartRow = ConvertUtil.convertToInt(listConfig.get(0).getStartrow());
        // 导入字段映射关系json格式
        String importFields = listConfig.get(0).getRelationships();
        // 必填字段
        String requiredFields = listConfig.get(0).getRequiredfields();
        // 填充数据
        String expandJsonDate = listConfig.get(0).getSupplement();
        // 转换字段
        String convertFields = listConfig.get(0).getConvertfields();
        Map<String, String> convertFieldsMap = (Map<String, String>) JSONUtil.parseJSONString(convertFields);
        // 唯一字段
        String uniqueFields = listConfig.get(0).getUniquefields();
        // 字段描述
        String descFields = listConfig.get(0).getDescfields();
        Map<String, String> fieldDescMap = (Map<String, String>) JSONUtil.parseJSONString(descFields);
        // 读取业务数据
        List<Map<String, String>> listDataMap;
        try {
            listDataMap = this.parseExcel(attachFile, attachFile.getName(), importFields, importStartRow);
        } catch (Exception e) {
            throw new ServiceException("excel读取失败");
        }
        // 删除无效行数据
        this.removeNoValidRow(listDataMap);
        if (listDataMap.size() == 0) {
            throw new ServiceException("excel表没有数据，请填写数据");
        }
        for (Map<String, String> map : listDataMap) {
            if (map.containsKey("planenddate") && ConvertUtil.convertToString(map.get("planenddate")).isEmpty()) {
                map.put("planenddate", tempTime);
            }
            if(map.containsKey("planenddate")){
                // 将各种格式的日期转化为通用格式 yyyy/MM/dd HH:mm:ss
                map.put("planenddate", mpmProjectMilepostService.formatVariousDate(map.get("planenddate")));
            }
        }
        // 转换字段
        this.convertExcelData(listDataMap, convertFieldsMap);
        // 自定义输入处理
        this.expandInputExcelData(listDataMap, paraMap);
        // 扩展处理，可以重写接口，实现特殊处理
        this.expandProcessExcelData(listDataMap);
        // 与数据库校验，校验长度、数据库类型是否合法
        this.checkDataBaseFieldValid(listDataMap, importStartRow);
        // 必填项校验
        this.checkDataRequired(listDataMap, requiredFields, fieldDescMap, importStartRow);
        // 唯一性校验
        this.checkDataUnique(listDataMap, uniqueFields, fieldDescMap, importStartRow);
        // 处理补充数据
        this.addDefaultData(expandJsonDate, listDataMap);
        // 处理数据
        List<Map<String, String>> dealtWithdata = this.dealtWithdata(businessFullScore, technologyFullScore, listDataMap, times, projectinfocode);
        // 删除所有存在数据
        this.deleteAllData(projectinfocode);
        // 数据入库
        this.executeInsertExcelData(dealtWithdata);
        return listDataMap.size();
    }

    /**
     * @Description: 删除所有数据
     * @Author: wuyuyang
     * @Return: void
     * @exception:
     * @Date: 14/2/2023 上午12:43
     * @Version: 1.0
     **/
    public void deleteAllData(String projectinfocode) {
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendSingle("projectcode = '{0}' and state != 1 and state != 9", projectinfocode);
        this.deleteByWhere(sql.toString());
    }

    /**
     * @Description: 过滤有效行数据
     * @Author: wuyuyang
     * @Return: void
     * @exception:
     * @Date: 11/2/2023 下午3:11
     * @Version: 1.0
     **/
    public void removeNoValidRow(List<Map<String, String>> listDataMap) {
        for (int i = 0; i < listDataMap.size(); ) {
            Map<String, String> map = listDataMap.get(i);
            boolean isExistValid = false;
            for (Map.Entry<String, String> entry : map.entrySet()) {
                String mapValue = entry.getValue();
                if (mapValue.length() > 0) {
                    isExistValid = true;
                }
            }
            if (isExistValid) {
                i++;
            } else {
                listDataMap.remove(i);
            }
        }
    }

    /**
     * @Description: 处理导入数据
     * @Author: wuyuyang
     * @Return: void
     * @exception:
     * @Date: 13/2/2023 上午2:34
     * @Version: 1.0
     **/
    @Transactional
    public List<Map<String, String>> dealtWithdata(String businessFullScore, String technologyFullScore, List<Map<String, String>> listDataMap, String times, String projectinfocode) {
        StringBuilder errorMessage = new StringBuilder();
        // 查询满分合计
        StringBufferProxy sql2 = new StringBufferProxy();
        sql2.appendSingle("projectcode = '{0}'and times = '{1}'and type = '{2}'", projectinfocode, times, MpmSystemConst.BidScoreType.firstType);
        // 商务满分合计
        List<MpmProjectBidFullScoreEntity> businessTotalfullsocre = mpmProjectBidFullScoreService.queryByWhere(sql2.toString());
        // 如果没有
        if (businessTotalfullsocre.size() == 0) {
            MpmProjectBidFullScoreEntity mpmProjectBidFullScoreEntity = new MpmProjectBidFullScoreEntity();
            mpmProjectBidFullScoreEntity.setType(MpmSystemConst.BidScoreType.firstType);
            mpmProjectBidFullScoreEntity.setTimes(times);
            mpmProjectBidFullScoreEntity.setProjectcode(projectinfocode);
            mpmProjectBidFullScoreEntity.setTotalfullsocre(businessFullScore);
            mpmProjectBidFullScoreService.insert(mpmProjectBidFullScoreEntity);
        } else {
            MpmProjectBidFullScoreEntity mpmProjectBidFullScoreEntity = new MpmProjectBidFullScoreEntity();
            mpmProjectBidFullScoreEntity.setType(MpmSystemConst.BidScoreType.firstType);
            mpmProjectBidFullScoreEntity.setTimes(times);
            mpmProjectBidFullScoreEntity.setProjectcode(projectinfocode);
            mpmProjectBidFullScoreEntity.setTotalfullsocre(businessFullScore);
            mpmProjectBidFullScoreService.updateEntity(mpmProjectBidFullScoreEntity);
        }
        Double businessTotalfullsocreDouble = new Double(businessFullScore);
        sql2.clear();
        sql2.appendSingle("projectcode = '{0}'and times = '{1}'and type = '{2}'", projectinfocode, times, MpmSystemConst.BidScoreType.secondType);
        // 技术满分合计
        List<MpmProjectBidFullScoreEntity> techTotalfullsocre = mpmProjectBidFullScoreService.queryByWhere(sql2.toString());
        if (techTotalfullsocre.size() == 0) {
            MpmProjectBidFullScoreEntity mpmProjectBidFullScoreEntity = new MpmProjectBidFullScoreEntity();
            mpmProjectBidFullScoreEntity.setType(MpmSystemConst.BidScoreType.secondType);
            mpmProjectBidFullScoreEntity.setTimes(times);
            mpmProjectBidFullScoreEntity.setProjectcode(projectinfocode);
            mpmProjectBidFullScoreEntity.setTotalfullsocre(technologyFullScore);
            mpmProjectBidFullScoreService.insert(mpmProjectBidFullScoreEntity);
        } else {
            MpmProjectBidFullScoreEntity mpmProjectBidFullScoreEntity = new MpmProjectBidFullScoreEntity();
            mpmProjectBidFullScoreEntity.setType(MpmSystemConst.BidScoreType.firstType);
            mpmProjectBidFullScoreEntity.setTimes(times);
            mpmProjectBidFullScoreEntity.setProjectcode(projectinfocode);
            mpmProjectBidFullScoreEntity.setTotalfullsocre(technologyFullScore);
            mpmProjectBidFullScoreService.updateEntity(mpmProjectBidFullScoreEntity);
        }
        Double techTotalfullsocreDouble = new Double(technologyFullScore);

        // 查询项目相关方
        StringBufferProxy sql = new StringBufferProxy();
        StringBufferProxy sql1 = new StringBufferProxy();
        sql.appendSingle("projectcode = '{0}'", projectinfocode);
        sql1.appendSingle("projectcode = '{0}'", projectinfocode);
        //查询项目信息
        MpmProjectEntity mpmProjectEntity = mpmProjectService.queryObjectByWhere(sql1.toString());
        // 检查负责人
        List<MpmProjectStakeholderEntity> mpmProjectStakeholderEntities = mpmProjectStakeholderService.queryByWhere(sql.toString());
        List<String> usernamelist = mpmProjectStakeholderEntities.stream().map(MpmProjectStakeholderEntity::getUsername).collect(Collectors.toList());
        String usernamecol = "," + usernamelist.toString().substring(1, usernamelist.toString().length() - 1).replaceAll(" ", "") + ",";
        // 获取流程id
        List<Map<String, Object>> approvalFlowListMap = flowDatacodeCache.getApprovalFlowListMap("ApprovalFlow_MpmProjectBidScore", this.getSessionUserBean(), "sortcode");
        List<Map<String, String>> listDataMap1 = new ArrayList<Map<String, String>>();
        if (listDataMap.size() > 0) {
            double businessScore = 0;
            double technologyScore = 0;
            for (Map<String, String> map : listDataMap) {
                String type = map.get(MpmProjectBidScoreEntity.FieldType);
                String index = ConvertUtil.convertToString(map.get("index"));
                String responsible = map.get(MpmProjectBidScoreEntity.FieldResponsible);
                if ("1".equals(times)) {
                    StringBufferProxy queryUserSql = new StringBufferProxy();
                    queryUserSql.appendSingle("name = '{0}' and enabled = 1 ", responsible);
                    List<CboUserEntity> userEntities = cboUserService.queryByWhere(queryUserSql.toString());
                    if (userEntities.size() == 0) {
                        errorMessage.append(spliceTips(type, index) + "责任人不存在；");
                    } else {
                        map.put(MpmProjectBidScoreEntity.FieldResponsiblecode, userEntities.get(0).getCode());
                    }
                } else {
                    responsible = "," + responsible + ",";
                    // 检查负责人
                    if (!(usernamecol.contains(responsible))) {
                        errorMessage.append(spliceTips(type, index) + "责任人不在项目相关方中；");
//                	throw new ServiceException();
                    }
                    // 遍历赋负责人工号
                    mpmProjectStakeholderEntities.stream().forEach(e -> {
                        if (map.get(MpmProjectBidScoreEntity.FieldResponsible).equals(e.getUsername())) {
                            map.put(MpmProjectBidScoreEntity.FieldResponsiblecode, e.getUsercode());
                        }
                    });
                }
                // 处理数据
                String fullScoreCheck = map.get(MpmProjectBidScoreEntity.FieldFullscore);
                String selfScoreCheck = map.get(MpmProjectBidScoreEntity.FieldSelfscore);
                String targetScoreCheck = map.get(MpmProjectBidScoreEntity.FieldTargetscore);
                String typeForScoreCheck = map.get(MpmProjectBidScoreEntity.FieldType);
                // 分开处理用户分数校验
                Map<String, String> fullScoreMap = this.dealtWithScore(fullScoreCheck, typeForScoreCheck, MpmProjectBidScoreEntity.FieldFullscore, map);
                Map<String, String> selfScoreMap = this.dealtWithScore(selfScoreCheck, typeForScoreCheck, MpmProjectBidScoreEntity.FieldSelfscore, fullScoreMap);
                Map<String, String> resMap = this.dealtWithScore(targetScoreCheck, typeForScoreCheck, MpmProjectBidScoreEntity.FieldTargetscore, selfScoreMap);

                //校验分数
                Double FieldFullscore = ConvertUtil.convertToDouble(resMap.get(MpmProjectBidScoreEntity.FieldFullscore));
                Double FieldSelfscore = ConvertUtil.convertToDouble(resMap.get(MpmProjectBidScoreEntity.FieldSelfscore));
                Double FieldTargetscore = ConvertUtil.convertToDouble(resMap.get(MpmProjectBidScoreEntity.FieldTargetscore));
//				Double FieldScoregap = ConvertUtil.convertToDouble(map.get(MpmProjectBidScoreEntity.FieldScoregap));
                // 比较不同类型满分合计
                if (resMap.get(MpmProjectBidScoreEntity.FieldType).equals("1")) {
                    if (Double.doubleToLongBits(FieldFullscore) > Double.doubleToLongBits(businessTotalfullsocreDouble)) {
                        errorMessage.append(spliceTips(type, index) + "满分大于满分合计；");
//						throw new ServiceException();
//						throw new ServiceException("商务类型满分不能大于满分合计");
                    }
                } else {
                    if (Double.doubleToLongBits(FieldFullscore) > Double.doubleToLongBits(techTotalfullsocreDouble)) {
//						throw new ServiceException("技术类型满分不能大于满分合计");
                        errorMessage.append(spliceTips(type, index) + "满分大于满分合计；");
//						throw new ServiceException(spliceTips(type,index) + "满分大于满分合计");
                    }
                }
                // 比较满分与自评分
                if (Double.doubleToLongBits(FieldFullscore) < Double.doubleToLongBits(FieldSelfscore)) {
//					String type = resMap.get(MpmProjectBidScoreEntity.FieldType).equals("1") ? "商务" : "技术";
//					String message = type + "类型中填写的自评分大于满分";
//					throw new ServiceException(message);
//					throw new ServiceException(spliceTips(type,index) + "自评分大于满分");
                    errorMessage.append(spliceTips(type, index) + "自评分大于满分；");
                }
                // 比较满分与目标得分
                if (Double.doubleToLongBits(FieldFullscore) < Double.doubleToLongBits(FieldTargetscore)) {
//					String type = resMap.get(MpmProjectBidScoreEntity.FieldType).equals("1") ? "商务" : "技术";
//					String message = type + "类型中填写的目标得分大于满分";
//					throw new ServiceException(message);
                    errorMessage.append(spliceTips(type, index) + "目标得分大于满分；");
//					throw new ServiceException(spliceTips(type,index) + "目标得分大于满分");
                }
                // 比较自评分和目标得分
                if (Double.doubleToLongBits(FieldTargetscore) < Double.doubleToLongBits(FieldSelfscore)) {
//					String type = resMap.get(MpmProjectBidScoreEntity.FieldType).equals("1") ? "商务" : "技术";
//					String message = type + "类型中填写的自评分大于目标得分";
//					throw new ServiceException(message);
                    errorMessage.append(spliceTips(type, index) + "自评分大于目标得分；");
//					throw new ServiceException(spliceTips(type,index) + "自评分大于目标得分");
                }
                // 赋予分差
                Double gap = sub(FieldFullscore, FieldSelfscore);
                // 判断是否小数,如果是保留一位小数，不是不做任何处理
                if (!isInteger(gap.toString())) {
                    // 截取最后一位判断是否为0
                    if (gap.toString().substring(gap.toString().length() - 1).equals("0")) {
                        DecimalFormat d = new DecimalFormat("0");
                        String CNY = d.format(gap);
                        resMap.put(MpmProjectBidScoreEntity.FieldScoregap, CNY);
                    } else {
                        DecimalFormat d = new DecimalFormat("0.0");
                        String CNY = d.format(gap);
                        resMap.put(MpmProjectBidScoreEntity.FieldScoregap, CNY);
                    }
                } else {
                    DecimalFormat d = new DecimalFormat("0");
                    String CNY = d.format(gap);
                    resMap.put(MpmProjectBidScoreEntity.FieldScoregap, CNY);
                }
                double scoregap = ConvertUtil.convertToDouble(resMap.get("scoregap"));
                // 检查时间是否合格
                String planFindate = map.get(MpmProjectBidScoreEntity.FieldPlanenddate);
                if (scoregap == 0 && !tempTime.equals(planFindate) && planFindate!=null) {
                    errorMessage.append(spliceTips(type, index) + "分差是0，不需填写完成时间；");
//					throw new ServiceException(spliceTips(type,index) + "分差是0，不需填写完成时间");
//					throw new ServiceException("分差是0，不需填写完成时间！");
                } else if (scoregap == 0 && tempTime.equals(planFindate) || planFindate == null) {
                    resMap.put(MpmProjectBidScoreEntity.FieldPlanenddate, "");
                } else if (scoregap != 0 && tempTime.equals(planFindate)) {
                    errorMessage.append(spliceTips(type, index) + "计划完成时间未填写；");
//					throw new ServiceException(spliceTips(type,index) + "计划完成时间未填写！");
                } else {
                    planFindate = planFindate.replace("/", "-");
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    long endtime = mpmProjectEntity.getPlanenddate().getTime();
                    long starttime = mpmProjectEntity.getPlanstartdate().getTime();
                    Date Findate;
                    try {
                        Findate = simpleDateFormat.parse(planFindate);
                    } catch (Exception e) {
                        Findate = null;
//						String type = map.get(MpmProjectBidScoreEntity.FieldType).equals("1") ? "商务" : "技术";
//						String message = type + "类型中填写的时间转换错误，请修改！";
//						throw new ServiceException(message);
//						errorMessage.append(spliceTips(type,index) + "计划完成时间转换错误间；");
                        throw new ServiceException(spliceTips(type, index) + "计划完成时间转换错误间");
                    }
                    // 完成时间处于计划中
                    if (!((Findate.getTime() >= starttime) && (Findate.getTime() <= endtime))) {
//						String type = map.get(MpmProjectBidScoreEntity.FieldType).equals("1") ? "商务" : "技术";
//						String message = type + "类型中填写的计划完成时间不在项目计划中!";
//						throw new ServiceException(message);
                        errorMessage.append(spliceTips(type, index) + "计划完成时间不在项目生命周期内；");
//						throw new ServiceException(spliceTips(type,index) + "计划完成时间不在项目计划中");
                    }
                }
                // map.put(MpmProjectBidScoreEntity.FieldScoregap, gap. toString());
//				if(!ConvertUtil.convertToString(FieldScoregap).equals(ConvertUtil.convertToString(gap))){
//					String type = map.get(MpmProjectBidScoreEntity.FieldType).equals("1") ? "商务" : "技术";
//					String message = type + "类型中填写的分查与满分和自评分的差值不相等";
//					throw new ServiceException(message);
//				}
                // 阶段次数
                resMap.put(MpmProjectBidScoreEntity.FieldTimes, times);
                // 流程id
                resMap.put(MpmProjectBidScoreEntity.FieldFlowid, approvalFlowListMap.get(0).get("id").toString());
                resMap.put(MpmProjectBidScoreEntity.FieldDeptcode, this.getSessionUserBean().getDept().getCode());
                resMap.put(MpmProjectBidScoreEntity.FieldDeptname, this.getSessionUserBean().getDept().getFullname());
                resMap.put(MpmProjectBidScoreEntity.FieldUsercode, this.getSessionUserBean().getUser().getCode());
                resMap.put(MpmProjectBidScoreEntity.FieldUsername, this.getSessionUserBean().getUser().getName());
                // 项目编号
                resMap.put(MpmProjectBidScoreEntity.FieldProjectcode, projectinfocode);
                // 赋单号
                long[] arrayId = PrimaryKeyUtil.GeneIDs(MpmProjectBidScoreEntity.tableName, 1);
                String docNo = String.valueOf(arrayId[0]);
                docNo = docNo.substring(0, 6) + docNo.substring(9);
                resMap.put(MpmProjectBidScoreEntity.FieldDocno, docNo);

                if ("1".equals(resMap.get("type"))) {
                    businessScore = businessScore + ConvertUtil.convertToDouble(resMap.get(MpmProjectBidScoreEntity.FieldFullscore));
                } else {
                    technologyScore = technologyScore + ConvertUtil.convertToDouble(resMap.get(MpmProjectBidScoreEntity.FieldFullscore));
                }

                listDataMap1.add(resMap);
            }
            if (businessScore > ConvertUtil.convertToDouble(businessFullScore)) {
//				throw new ServiceException("填写的商务总分大于满分合计");
                errorMessage.append("填写的商务总分大于满分合计；");
            }
            if (technologyScore > ConvertUtil.convertToDouble(technologyFullScore)) {
//				throw new ServiceException("填写的技术总分大于满分合计");
                errorMessage.append("填写的技术总分大于满分合计；");
            }
            if (errorMessage.toString().length() > 0) {
                throw new ServiceException(errorMessage.toString());
            }
            return listDataMap1;
        }
        return null;
    }

    public String spliceTips(String type, String index) {
        StringBuilder str = new StringBuilder();
        if ("1".equals(type)) {
            str.append("商务中的第");
        } else {
            str.append("技术中的第");
        }
        str.append(index).append("行");
        return str.toString();
    }

    /**
     * @Description: double值减法
     * @Author: wuyuyang
     * @Return: java.lang.Double
     * @exception:
     * @Date: 15/2/2023 下午6:10
     * @Version: 1.0
     **/
    public Double sub(Double value1, Double value2) {
        BigDecimal b1 = new BigDecimal(Double.toString(value1));
        BigDecimal b2 = new BigDecimal(Double.toString(value2));
        return b1.subtract(b2).doubleValue();
    }

    /**
     * @Description: 解析excel，返回List<Map>集合， fields：导出字段，使用","作为分隔符 startRow：起始行
     * @Author: wuyuyang
     * @Return: java.util.List<java.util.Map < java.lang.String, java.lang.String>>
     * @exception:
     * @Date: 13/2/2023 上午9:46
     * @Version: 1.0
     **/
    public List<Map<String, String>> parseExcel(File attachFile, String fileName, String fields, int startRow)
            throws Exception {
        if (!fileName.endsWith("xlsx")) {
            throw new BusinessException("非法文件格式，请选择使用Excel2007！");
        }
        // 从参数表获取导入列配置信息
        String[] arrayFields = fields.split(",");
        Map<String, String> mapColumn = new HashMap<String, String>();
        int index_i = 0;
        for (int i = 0; i < arrayFields.length; i++) {
            index_i = arrayFields[i].indexOf(":");
            // 如果没有设置对应字段，不需要处理数据。
            if ((index_i + 1) == arrayFields[i].length()) {
                continue;
            }
            // 如果设置为-1，不需要处理数据。
            if ("-1".equals(arrayFields[i].substring(index_i + 1))) {
                continue;
            }
            mapColumn.put(arrayFields[i].substring(0, index_i), arrayFields[i].substring(index_i + 1));
        }
        // 从1开始的行
        startRow = startRow - 1;
        List<Map<String, String>> listDataMap = new ArrayList<Map<String, String>>();
        List<Map<String, String>> reslistDataMap = new ArrayList<Map<String, String>>();
        List<Map<String, String>> listDataMap1 = new ArrayList<Map<String, String>>();
        Workbook wb = null;
        try {
            InputStream input = new FileInputStream(attachFile); // 建立输入流
            wb = new XSSFWorkbook(input);
            Sheet sheet = wb.getSheetAt(0); // 获得第一个表单
            // 备份startRow 和 mapColumn1
            int startRow1 = startRow;
            Map<String, String> mapColumn1 = mapColumn;
            // 处理商务sheet
            List<Map<String, String>> sheetData1 = this.dealtWithSheet(MpmSystemConst.BidScoreType.firstType, sheet, listDataMap, startRow, mapColumn);
            // 处理技术sheet
            Sheet sheet1 = wb.getSheetAt(1); // 获得第二个表单
            List<Map<String, String>> sheetData2 = this.dealtWithSheet(MpmSystemConst.BidScoreType.secondType, sheet1, listDataMap1, startRow1, mapColumn1);
            reslistDataMap.addAll(sheetData1);
            reslistDataMap.addAll(sheetData2);
        } catch (IOException ex) {
            throw new BusinessException(ex);
        } finally {
            if (wb != null) {
                wb.close();
            }
        }
        return reslistDataMap;
    }

    /**
     * @Description: 处理sheet页数据
     * @Author: wuyuyang
     * @Return: java.util.List<java.util.Map < java.lang.String, java.lang.String>>
     * @exception:
     * @Date: 13/2/2023 上午10:29
     * @Version: 1.0
     **/
    public List<Map<String, String>> dealtWithSheet(String type, Sheet sheet, List<Map<String, String>> listDataMap, int startRow, Map<String, String> mapColumn) {
        Iterator<Row> rows = sheet.rowIterator(); // 获得表单的迭代器
        NumberFormat numberFormat = NumberFormat.getNumberInstance();
        numberFormat.setGroupingUsed(false);
        if (rows.hasNext()) {// 跳过第一行
            rows.next();
        }
        for (int i = startRow; i <= sheet.getLastRowNum(); i++) {
            Row row = sheet.getRow(i); // 获得行数据
            if (row == null) {
                break;
            }
            Map<String, String> rowData = new HashMap<String, String>();
            for (String key : mapColumn.keySet()) {
                Cell cell = row.getCell(Integer.parseInt(mapColumn.get(key)) - 1);
                if (cell == null)
                    continue;
                if (cell.getCellType() == CellType.NUMERIC && HSSFDateUtil.isCellDateFormatted(cell)) {
                    rowData.put(key, DateUtil.dateToString(cell.getDateCellValue(), "yyyy/MM/dd HH:mm:ss"));
                } else if (CellType.NUMERIC.equals(cell.getCellType())) {
                    double d = cell.getNumericCellValue();
                    rowData.put(key, numberFormat.format(d));
                } else {
                    cell.setCellType(CellType.STRING);
                    rowData.put(key, cell.getStringCellValue());
                }
            }
            listDataMap.add(rowData);
        }
        // 清除多余数据
        this.removeNoValidRow(listDataMap);
        List<Map<String, String>> listDataMap1 = new ArrayList<Map<String, String>>();
        // 赋予类型
        int index = 2;
        for (Map<String, String> map : listDataMap) {
            map.put(MpmProjectBidScoreEntity.FieldType, type);
            map.put("index", index + "");
            index++;
            listDataMap1.add(map);
        }
        return listDataMap1;
    }

    // 处理key值
    public String dealtWithKey(String key) {
        if (key.equals(MpmProjectBidScoreEntity.FieldFullscore)) {
            return "满分";
        } else if (key.equals(MpmProjectBidScoreEntity.FieldSelfscore)) {
            return "自评分";
        } else if (key.equals(MpmProjectBidScoreEntity.FieldTargetscore)) {
            return "目标得分";
        } else if (key.equals(MpmProjectBidScoreEntity.FieldScoregap)) {
            return "分差";
        } else {
            return "";
        }
    }

    /**
     * 判断字符串是否是整数
     */
    private static boolean isInteger(String value) {
        try {
            Integer.parseInt(value);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    /**
     * @Description: 重写插入方法
     * @Author: wuyuyang
     * @Return: void
     * @exception:
     * @Date: 15/2/2023 下午7:44
     * @Version: 1.0
     **/
    @Override
    public void executeInsertExcelData(List<Map<String, String>> listDataMap) {
        List<BasicEntity> listInsert = new ArrayList<BasicEntity>();
        // 检索判断计划完成时间
        for (Map<String, String> map : listDataMap) {
            String fullscore = map.get(MpmProjectBidScoreEntity.FieldFullscore);
            String selfscore = map.get(MpmProjectBidScoreEntity.FieldSelfscore);
            String planenddate = map.get(MpmProjectBidScoreEntity.FieldPlanenddate);
            // 相等情况下不需要填写计划完成时间
            if (fullscore.equals(selfscore)) {
                if (!StringUtils.isEmpty(planenddate)) {
                    String type = map.get(MpmProjectBidScoreEntity.FieldType);
                    String typemessage = type.equals("1") ? "商务" : "技术";
                    String message = typemessage + "类型中不需要填写计划完成时间";
                    throw new ServiceException(message);
                }
                // 不等情况下计划完成时间必填
            } else {
                if (StringUtils.isEmpty(planenddate)) {
                    String type = map.get(MpmProjectBidScoreEntity.FieldType);
                    String typemessage = type.equals("1") ? "商务" : "技术";
                    String message = typemessage + "类型中计划完成时间必填，请修改！";
                    throw new ServiceException(message);
                }
            }
        }
        for (Map mapRow : listDataMap) {
            Class c = this.getDao().getEntityClass();
            BasicEntity baseEntity;
            try {
                baseEntity = (BasicEntity) c.newInstance();
                baseEntity = baseEntity.convertFromMap(mapRow);
                if (baseEntity == null)
                    continue;
                listInsert.add(baseEntity);
            } catch (Exception e) {
                throw new ServiceException("导入失败");
            }
        }
        this.insertBatch(listInsert);
    }


//	public void ispositivenumber(double data, String type ) {
//		if(data < -(1e-8) ){
//			String typemessage = type.equals("1") ? "商务" : "技术";
//			String message = typemessage + "类型中填写的数字小于0";
//			throw new ServiceException(message);
//		}
//
//	}

    /**
     * @Description: 校验分数
     * @Author: wuyuyang
     * @Return: boolean
     * @exception:
     * @Date: 15/2/2023 下午10:29
     * @Version: 1.0
     **/
    public Map<String, String> dealtWithScore(String score, String type, String key, Map<String, String> map) {
        Double cny = null;
        try {
            cny = Double.parseDouble(score);
            double v = cny.doubleValue();
            // 判断是否小于0
            if (v < -(1e-8)) {
                String typemessage = type.equals("1") ? "商务" : "技术";
                String message = typemessage + "类型中填写的" + this.dealtWithKey(key) + "不符合规范";
                throw new ServiceException(message);
            }
            // 判断是否小数,如果是保留一位小数，不是不做任何处理
            if (!isInteger(score)) {
                // 截取最后一位判断是否为0
                if (cny.toString().substring(cny.toString().length() - 1).equals("0")) {
                    DecimalFormat d = new DecimalFormat("0");
                    String CNY = d.format(cny);
                    map.put(key, CNY);
                } else {
                    // 判断用户填入数字小数部分长度大于1，就抛出错误
                    String res = score;
                    String[] split = res.split("\\.");
                    if (split[1].length() != 1) {
                        String typemessage = type.equals("1") ? "商务" : "技术";
                        String message = typemessage + "类型中填写的" + this.dealtWithKey(key) + "不符合规范";
                        throw new ServiceException(message);
                    }
                    DecimalFormat d = new DecimalFormat("0.0");
                    String CNY = d.format(cny);
                    map.put(key, CNY);
                }
            } else {
                DecimalFormat d = new DecimalFormat("0");
                String CNY = d.format(cny);
                map.put(key, CNY);
            }

        } catch (Exception e) {
            String typemessage = type.equals("1") ? "商务" : "技术";
            String message = typemessage + "类型中填写的" + this.dealtWithKey(key) + "不符合规范";
            throw new ServiceException(message);
        }
        return map;
    }

    /**
     * 三阶段自评list接口
     * @author xinfushuo
     * @param
     * @throws
     * @return
     * @date 2023/3/8
     * @modify
     */
    @Override
    public List<Map<String, Object>> threePhaseBidScore(Map<String, Object> paraMap) {
        List<Map<String, Object>> list = this.queryMap(paraMap, "querythreephase");
        this.setDispFields(list);
        //处理合计
        Map<String, Object> sumObj =
                list.stream().flatMap(m -> m.entrySet().stream()).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2) -> {
                    if (v1 instanceof Number) {
                        return ((Number) v1).intValue() + ((Number) v2).intValue();
                    }
                    return "";
                }));
        sumObj.put("dispdeptcommoncode", "合计");
        if (!list.isEmpty()) {
            //处理合计录入率
            BiFunction<Object, Object, String> divide = (x, y) -> {
                int x1 = ((Number) x).intValue();
                int y1 = ((Number) y).intValue();
                if (y1 == 0) {
                    return "/";
                } else if (x1 == 0) {
                    return "0%";
                } else {
                    return Math.round((float) x1 / (float) y1 * 100) + "%";
                }
            };
            sumObj.put("first_rate", divide.apply(sumObj.get("first_actualsum"), sumObj.get("first_expectsum")));
            sumObj.put("second_rate", divide.apply(sumObj.get("second_actualsum"), sumObj.get("second_expectsum")));
            sumObj.put("third_rate", divide.apply(sumObj.get("third_actualsum"), sumObj.get("third_expectsum")));
            list.add(sumObj);
        }
        return list;
    }
    /**
     * @description:  导入历史项目第三阶段自评
     * @author houyuhang
     * @date 2023/4/14
     * @modify
     */
    @Transactional
    public void addFirstBidScoreHistory(Map<String, Object> paraMap) {
        if (!paraMap.containsKey("oldprojectcode") || !paraMap.containsKey("newprojectcode")) {
            throw new ServiceException("未获取项目编号，请联系管理员！");
        }
        // 删除项目第一阶段自评内容
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendSingle(" projectcode = '{0}' and times = '{1}' and state in ('0', '2') ", paraMap.get("newprojectcode"), MpmSystemConst.BidScoreTimes.firstTime);
        this.deleteByWhere(sql.toString());
        // 获取历史项目第三阶段自评
        sql.clear();
        sql.appendSingle(" projectcode = '{0}' and times = '{1}' and type in ({2}) ", ConvertUtil.convertToString(paraMap.get("oldprojectcode")), MpmSystemConst.BidScoreTimes.thirdTime, MpmSystemConst.BidScoreType.firstType + "," + MpmSystemConst.BidScoreType.secondType);
        List<MpmProjectBidScoreEntity> threeBidEntities = this.queryByWhere(sql.toString());
        if (CollectionUtil.isEmpty(threeBidEntities)) {
            return;
        }
        // 生成第一阶段自评
        for (MpmProjectBidScoreEntity entity : threeBidEntities) {
            entity.setId(0L);
            entity.setTimes(MpmSystemConst.BidScoreTimes.firstTime);
            entity.setProjectcode(ConvertUtil.convertToString(paraMap.get("newprojectcode")));
            entity.setState(0);
            entity.setUsercode(ConvertUtil.convertToString(paraMap.get("usercode")));
            entity.setUsername(ConvertUtil.convertToString(paraMap.get("username")));
            entity.setSubmitdate(null);
            entity.setLatestphase(null);
            this.insert(entity);
        }
    }
    /**
     * @author: houyuhang
     * @date: 2023-06-05
     * @param paraMap
     * @return
     * @description:secondshow为TRUE,firstedit、secondedit非招标项目为false，招标项目挂网日期前第一次自评可填写，挂网-开标第二次自评可填写
     * @modify:
     */
    @Transactional
    public Map<String, Object> queryScoreInfo(Map<String, Object> paraMap) {
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("secondshow", true);
        String projectcode = ConvertUtil.convertToString(paraMap.get("projectcode"));
        // 获取项目的采购模式
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendSingle(" id in (select id from mpmproject where projectcode = '{0}') ", projectcode);
        MpmProjectSaleEntity mpmProjectSaleEntity = mpmProjectSaleService.queryObjectByWhere(sql.toString());
        if (ObjectUtil.isEmpty(mpmProjectSaleEntity)) {
            throw new MessageException("评分细则未找到项目，请联系管理员！");
        }
        String purchasepattern = mpmProjectSaleEntity.getPurchasepattern();
        Date bidbegindate = mpmProjectSaleEntity.getBidbegindate();
        Date bidenddate = mpmProjectSaleEntity.getBidenddate();
        // 获取项目的第一、二阶段审批中自评信息
        sql.clear();
        sql.appendSingle(" projectcode = '{0}' and times in ({1}) and type in ({2}) and state = 1 ", projectcode, MpmSystemConst.BidScoreTimes.firstTime + "," + MpmSystemConst.BidScoreTimes.secondTime, MpmSystemConst.BidScoreType.firstType + "," + MpmSystemConst.BidScoreType.secondType);
        List<MpmProjectBidScoreEntity> bidScoreEntities = this.queryByWhere(sql.toString());
        boolean firstBidFlag = bidScoreEntities.stream().anyMatch(item -> MpmSystemConst.BidScoreTimes.firstTime.equals(item.getTimes()));
        boolean secondBidFlag = bidScoreEntities.stream().anyMatch(item -> MpmSystemConst.BidScoreTimes.secondTime.equals(item.getTimes()));
        if (MpmSystemConst.PurchasePattern.chanpinBid.equals(purchasepattern) || MpmSystemConst.PurchasePattern.fuwuBid.equals(purchasepattern) || MpmSystemConst.PurchasePattern.dianshang.equals(purchasepattern)) {
            // 挂网开标日期不存在的历史数据
            if (bidbegindate == null || bidenddate == null) {
                resultMap.put("firstedit", true);
                resultMap.put("secondedit", true);
            } else {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(bidbegindate);
                bidbegindate = ConvertTimeUtil.convertToTomorrow(calendar).getTime();
                calendar.setTime(bidenddate);
                bidenddate = ConvertTimeUtil.convertToTomorrow(calendar).getTime();
                if (new Date().compareTo(bidbegindate) < 0) {
                    resultMap.put("firstedit", true);
                    resultMap.put("secondedit", false);
                } else if (new Date().compareTo(bidenddate) > 0) {
                    resultMap.put("firstedit", false);
                    resultMap.put("secondedit", false);
                } else {
                    resultMap.put("firstedit", false);
                    resultMap.put("secondedit", true);
                }
            }
            // 如果存在第一、二阶段自评审批中单据，不允许编辑
            if (firstBidFlag) {
                resultMap.put("firstedit", false);
            }
            if (secondBidFlag) {
                resultMap.put("secondedit", false);
            }
        } else {
            resultMap.put("firstedit", false);
            resultMap.put("secondedit", false);
        }
        return resultMap;
    }
    /**
     * @author: houyuhang
     * @date: 2023-06-05
     * @return
     * @description:赋值flowid
     * @modify:
     */
    @Override
    protected void beforeSubmit(TapEntity entity, SessionUserBean sessionUserBean) {
        super.beforeSubmit(entity, sessionUserBean);
        MpmProjectBidScoreEntity bidScoreEntity  = (MpmProjectBidScoreEntity) entity;
        this.flowidList= flowDatacodeCache
                .getApprovalFlowListMap("ApprovalFlow_MpmProjectBidScore",
                        bidScoreEntity.getUsercode(), "sortcode");
        if(flowidList.size()>0){
            bidScoreEntity.setFlowid(ConvertUtil.convertToLong(flowidList.get(0).get("id")));
        }else{
            throw new ServiceException("没有匹配的审批流，请联系管理员！");
        }
    }
}
